﻿using System;
using System.IO;
using System.Net;
using System.Linq;
using System.Text;
using System.Activities;
using System.Activities.Expressions;
using System.Activities.Presentation.PropertyEditing;
using System.Activities.Statements;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel;
using System.Windows.Markup;
using Microsoft.Reporting.WinForms;

namespace Vision.Core.ActivityComponents.Sql
{
    /// <summary>
    /// 
    /// </summary>
    [ContentProperty("Body")]
    [System.ComponentModel.Designer(typeof(SqlExecuteReportDesigner))]
    public class SqlExecuteReport : NativeActivity
    {
        /// <summary>
        /// 
        /// </summary>
        [Browsable(false)]
        [DefaultValue(null)]
        public ActivityAction<byte[]> Body { get; set; }
        
        /// <summary>
        /// 
        /// </summary>
        [Category("Input")]
        [RequiredArgument]
        [DefaultValue(null)]
        public InArgument<string> ReportServerUrl { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [Category("Input")]
        [RequiredArgument]
        [DefaultValue(null)]
        public InArgument<string> ReportPath { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [Category("Input")]        
        [DefaultValue(null)]
        public InArgument<Dictionary<string, string>> ReportParameters { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [Category("Input")]        
        [DefaultValue(null)]
        public InArgument<string> AuthDomain { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [Category("Input")]        
        [DefaultValue(null)]
        public InArgument<string> AuthUser { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [Category("Input")]        
        [DefaultValue(null)]
        public InArgument<string> AuthPassword { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [Category("Input")]        
        [DefaultValue(null)]
        public InArgument<string> ExportType { get; set; }
        
        /// <summary>
        /// 
        /// </summary>
        [Category("Output")]        
        [DefaultValue(null)]
        public OutArgument<byte[]> ReportData { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public SqlExecuteReport(): base()
        {
            this.Body = new ActivityAction<byte[]>(){
                Argument = new DelegateInArgument<byte[]>() { Name = "bytes" }
            };
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="metadata"></param>
        protected override void CacheMetadata(NativeActivityMetadata metadata)
        {
            // add the arguments to the argument collection
            metadata.AddArgument(new RuntimeArgument("ReportServerUrl", typeof(string), ArgumentDirection.In, true));
            metadata.AddArgument(new RuntimeArgument("ReportPath", typeof(string), ArgumentDirection.In, true));
            metadata.AddArgument(new RuntimeArgument("ReportParameters", typeof(Dictionary<string, string>), ArgumentDirection.In, false));
            metadata.AddArgument(new RuntimeArgument("AuthDomain", typeof(string), ArgumentDirection.In, false));
            metadata.AddArgument(new RuntimeArgument("AuthUser", typeof(string), ArgumentDirection.In, false));
            metadata.AddArgument(new RuntimeArgument("AuthPassword", typeof(string), ArgumentDirection.In, false));
            metadata.AddArgument(new RuntimeArgument("ExportType", typeof(string), ArgumentDirection.In, false));
            metadata.AddArgument(new RuntimeArgument("ReportData", typeof(byte[]), ArgumentDirection.Out, false));

            // add the body to the delegates collection
            metadata.AddDelegate(this.Body);    
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        protected override void Execute(NativeActivityContext context)
        {
            ReportViewer ctlReportViewer = new ReportViewer();            
            ctlReportViewer.ProcessingMode = ProcessingMode.Remote;
            ctlReportViewer.ServerReport.ReportServerUrl = new Uri(context.GetValue(this.ReportServerUrl));
            ctlReportViewer.ServerReport.ReportPath = context.GetValue(this.ReportPath);
            ctlReportViewer.ServerReport.ReportServerCredentials.NetworkCredentials = new NetworkCredential(context.GetValue(this.AuthUser), context.GetValue(this.AuthPassword), context.GetValue(this.AuthDomain));

            Dictionary<string, string> parameters = context.GetValue(this.ReportParameters);
            if (parameters != null){
                foreach (string param in parameters.Keys){
                    ctlReportViewer.ServerReport.SetParameters(new ReportParameter(param, parameters[param]));
                }
            }                                    
            
            byte[] report = ctlReportViewer.ServerReport.Render(context.GetValue(this.ExportType));
            context.SetValue(this.ReportData, report);            
        }        
    }
}
